
#include "ui_mainwindow.h"
#include "mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent), ui(new Ui::MainWindow)
{
     ui->setupUi(this);
     ui->menuSomething->hide();

     // list the possible statistics in combo box
     QStringList xstats, ystats;
     xstats << "Masters" << "Max Packet Size"<< "Min Packet Size" << "Speed";
     ystats << "Collisions" << "Received"<< "Avg Speed"<<"Avg Packet Size";
     ui->XcomboBox->insertItems(0, xstats);
     ui->YcomboBox->insertItems(0, ystats);


     paramsWindow = new GetParams(this);

     drawSim = new DrawSim(this);

     plotWindow = new Plot(this);

     Ethernet *network = new Ethernet(this);

     nextSimTimer = new QTimer(this);
     displayTimer = new QTimer(this);

     simCount = 0; // increment when you start a new sim

     simData = new SimData();
     simDataArray[simCount] = simData;
     simDataArray[simCount]->simIndex = simCount;
     simDataArray[simCount]->masters = 0;
     simDataArray[simCount]->maxpacket = 0;
     simDataArray[simCount]->minpacket = 0;
     simDataArray[simCount]->speed = 0;

     drawSim->setAutoFillBackground(true);
     QRect r(QPoint(60,320),QSize(621,321));
     drawSim->setGeometry(r);

     QObject::connect( this, SIGNAL( showSignal() ), &*paramsWindow, SLOT( shown() ) );

     QObject::connect( &*paramsWindow, SIGNAL( paramsSaved(int,int,int,int) ), this, SLOT( saveParams(int,int,int,int) ) );
     QObject::connect( &*paramsWindow, SIGNAL( paramsNotSaved() ), this, SLOT(dontSaveParams() ) );

     QObject::connect( this, SIGNAL( mastersChanged(int) ), &*drawSim, SLOT( changeMasters(int) ) );
     QObject::connect( this, SIGNAL( zoomChanged(int) ), &*drawSim, SLOT( changeZoom(int) ) );
     QObject::connect( this, SIGNAL( drawMasterAction(int, int) ), &*drawSim, SLOT( masterAction(int, int) ) );
     QObject::connect( this, SIGNAL( drawEnetStatus(int ) ), &*drawSim, SLOT( ethernetStatus(int ) ) );

     QObject::connect( this, SIGNAL( startTheSim(int,int,int,int) ), network, SLOT( start(int,int,int,int) ) );
     QObject::connect( this, SIGNAL( stopTheSim() ), network, SLOT( stop() ) );

     QObject::connect( network, SIGNAL( enetStatusSignal( int ) ), this, SLOT( ethernetStatus(int ) ) );
     QObject::connect( network, SIGNAL( masterActionSignal( int , int ) ), this, SLOT( masterAction(int, int) ) );

     connect(nextSimTimer, SIGNAL(timeout()), this, SLOT(nextSim()) );
     connect(displayTimer, SIGNAL(timeout()), this, SLOT(displayStats()) );

     // initialize start/stop flag
     keepGoing = false;

     parameterSaved = false;

     displayTimer->start(1000);

 }

void MainWindow::displayStats()
{

    switch(ui->XcomboBox->currentIndex())
    {
    case 0: // write to x text edit
        xWrite(tr(" %1 ").arg(simDataArray[simCount]->masters));
        break;
    case 1: // write to x text edit
        xWrite(tr(" %1 ").arg(simDataArray[simCount]->maxpacket));
        break;
    case 2: // write to x text edit
        xWrite(tr(" %1 ").arg(simDataArray[simCount]->minpacket));
        break;
    case 3: // write to x text edit
        xWrite(tr(" %1 ").arg(simDataArray[simCount]->speed));
        break;
    }

    switch(ui->YcomboBox->currentIndex())
    {
    case 0:
        yWrite(tr(" %1 ").arg(simDataArray[simCount]->colisions));
        break;
    case 1:
        yWrite(tr(" %1 ").arg(simDataArray[simCount]->received));
        break;
    case 2:
        break;
    case 3:
        break;
    }

}

void MainWindow::xWrite(QString str)
{
    ui->xTextEdit->setPlainText(str);
}
void MainWindow::yWrite(QString str)
{
    ui->yTextEdit->setPlainText(str);
}

void MainWindow::masterAction(int masterIndex, int action )
{
    emit drawMasterAction(masterIndex, action);
    if(action == 3)
    {
        trace(tr("Master %1 is checking.").arg(masterIndex));
    }
    else if( action == 2)
    {
        trace(tr("Master %1 is sending a packet.").arg(masterIndex));
    }
    else if(action == 1)
    {
        simDataArray[simCount]->received++;
        trace(tr("Master %1 received a packet.").arg(masterIndex));
    }
}

// receives a signal from the ethernet about its status
void MainWindow::ethernetStatus(int status)
{
   emit drawEnetStatus(status);
   if( status == 1) //colision
   {
       simDataArray[simCount]->colisions++;
       trace(tr("Collision %1.").arg(simDataArray[simCount]->colisions));
   }
}

void MainWindow::on_zoomSlider_valueChanged()
{
    int zoom;
    zoom = ui->zoomSlider->value();

    emit zoomChanged(zoom);
}

void MainWindow::saveParams(int masters, int max, int min, int speed)
{


    simDataArray[simCount]->masters = masters;
    simDataArray[simCount]->maxpacket = max;
    simDataArray[simCount]->minpacket = min;
    simDataArray[simCount]->speed = speed;

    if(masters<2)
    {simDataArray[simCount]->masters=2;
    }
    if(max<1)
    {simDataArray[simCount]->maxpacket= 100;
    }
    if(min<1)
    {simDataArray[simCount]->minpacket= 1;
    }
    if(speed<1)
    {simDataArray[simCount]->speed= 1;
    }


    paramsWindow->hide();

    parameterSaved = true;

    emit mastersChanged(masters);

}

void MainWindow::dontSaveParams()
{
    parameterSaved = false;

    paramsWindow->hide();
}


// shows a window that will save user simulation data
void MainWindow::on_paramsButton_clicked()
{
    // checks and sets the multiSim flag
    if(ui->singleSimButton->isChecked()){
        paramsWindow->multiSimTrue = false;
    }
    else{
        paramsWindow->multiSimTrue = true;
    }

    paramsWindow->show();


    emit showSignal();
}

void MainWindow::on_ShowGraphButton_clicked()
{
    plotWindow->show();
}

//destructor
MainWindow::~MainWindow()
{
    delete simData;
    delete paramsWindow;
    delete drawSim;
    delete plotWindow;
    delete ui;
}


void MainWindow::trace(QString str)
{
    ui->SimOutText->appendPlainText(str);
}

void MainWindow::paramAutoGen()
{
    if(ui->singleSimButton->isChecked())
    {
        simDataArray[simCount]->masters = random()%50 + 2;
    }
    else{
        simDataArray[simCount]->masters = 2;
    }

    emit mastersChanged(simDataArray[simCount]->masters);
    simDataArray[simCount]->maxpacket = random()%200 + 700;
    simDataArray[simCount]->minpacket = random()%300+200;
    simDataArray[simCount]->speed = random()%99 + 1;

}

void MainWindow::on_StartButton_clicked()
{


    if(!keepGoing)
    {
      if(ui->multiSimButton->isChecked())
      {
         qDebug() << "setting timer";
         nextSimTimer->start(20000);
      }

      if( !parameterSaved)
      {
          paramAutoGen();
      }

      keepGoing = true;
      emit startTheSim(simData->masters, simData->maxpacket, simData->minpacket, simData->speed);
    }else{

      if(ui->multiSimButton->isChecked())
      {
         nextSimTimer->stop();
      }
      keepGoing = false;
      simCount++;
      simData = new SimData();
      simDataArray[simCount] = simData;
      simDataArray[simCount]->simIndex = simCount;
      emit stopTheSim();
    }

}

void MainWindow::nextSim()
{
    if(keepGoing)
    {
        emit stopTheSim();

        simCount++;
        simData = new SimData();
        simDataArray[simCount] = simData;
        simDataArray[simCount]->simIndex = simCount;

        simDataArray[simCount]->masters = simDataArray[simCount-1]->masters + 1;
        simDataArray[simCount]->maxpacket = simDataArray[simCount-1]->maxpacket ;
        simDataArray[simCount]->minpacket = simDataArray[simCount-1]->minpacket ;
        simDataArray[simCount]->speed = simDataArray[simCount-1]->speed ;
 emit mastersChanged(simDataArray[simCount]->masters);
        emit startTheSim(simData->masters, simData->maxpacket, simData->minpacket, simData->speed);
    }
}


void MainWindow::on_actionNew_triggered()
{
    trace("Getting File path and name to save.");
    FilePath = QFileDialog::getSaveFileName(this);

    simFile.setFileName(FilePath);

    if(simFile.open(QIODevice::ReadWrite| QIODevice::Text))
    {
        trace("File created:");
        trace(FilePath);
        simFile.close();
    }

}


void MainWindow::on_actionOpen_triggered()
{
    trace("Getting File path and name to open.");
    FilePath = QFileDialog::getOpenFileName(this);
     simFile.setFileName(FilePath);

     bool ok;
     int thisSimCount = 0;

    if(simFile.open(QIODevice::ReadWrite| QIODevice::Text))
    {
        trace("File opened:");
        qDebug() << "File opened :" << FilePath;
        trace(FilePath);

       QTextStream in(&simFile);
               if (!in.atEnd()) {
                      QString line = in.readLine();
                      line.clear();

               }
               if (!in.atEnd()) {
                      QString line = in.readLine();
                      thisSimCount = line.toInt(&ok, 10);
                      simCount = thisSimCount;
                      simCount;
                      qDebug() << "simCount :" << simCount;
               }



               for(int i = 0; i < thisSimCount;i++)
               {
                   simData = new SimData;
                   simDataArray[i] = simData;

                   if (!in.atEnd()) {
                          QString line = in.readLine();
                          line.clear();
                   }
                   if (!in.atEnd()) {
                          QString line = in.readLine();
                          simDataArray[i]->simIndex  = line.toInt(&ok, 10);
                          qDebug() << "simIndex :" << simDataArray[i]->simIndex;
                   }
                   if (!in.atEnd()) {
                          QString line = in.readLine();
                          line.clear();
                   }
                   if (!in.atEnd()) {
                          QString line = in.readLine();
                          simDataArray[i]->masters = line.toInt(&ok, 10);

                   }
                   if (!in.atEnd()) {
                          QString line = in.readLine();
                          line.clear();
                   }
                   if (!in.atEnd()) {
                          QString line = in.readLine();
                          simDataArray[i]->maxpacket  = line.toInt(&ok, 10);
                   }
                   if (!in.atEnd()) {
                          QString line = in.readLine();
                          line.clear();
                   }
                   if (!in.atEnd()) {
                          QString line = in.readLine();
                          simDataArray[i]->minpacket  = line.toInt(&ok, 10);
                   }
                   if (!in.atEnd()) {
                          QString line = in.readLine();
                          line.clear();
                   }
                   if (!in.atEnd()) {
                          QString line = in.readLine();
                          simDataArray[i]->colisions  = line.toInt(&ok, 10);
                   }
                   if (!in.atEnd()) {
                          QString line = in.readLine();
                          line.clear();
                   }
                   if (!in.atEnd()) {
                          QString line = in.readLine();
                           simDataArray[i]->received  = line.toInt(&ok, 10);
                   }

               }

               simData = new SimData;
               simDataArray[simCount] = simData;
               simDataArray[simCount]->simIndex = simCount;
               simDataArray[simCount]->masters = 0;
               simDataArray[simCount]->maxpacket = 0;
               simDataArray[simCount]->minpacket = 0;
               simDataArray[simCount]->colisions = 0;
               simDataArray[simCount]->received = 0;
               simDataArray[simCount]->speed = 0;

       simFile.close();


    }
    qDebug() << "closed ok.";

}

void MainWindow::on_actionSave_triggered()
{
    trace("Saving File.");
    if(!(simFile.open(QIODevice::ReadWrite| QIODevice::Text)))
    {

        trace("No File to save.");

        trace("Getting File path and name to save.");
        FilePath = QFileDialog::getSaveFileName(this);

        simFile.setFileName(FilePath);

        if(simFile.open(QIODevice::ReadWrite| QIODevice::Text))
        {
            trace("File created:");

            QTextStream out(&simFile);
            out << "Number of simulations run:\n" << simCount << "\n";
            for(int i = 0; i <simCount; i++)
            {
                out << "Simulation number:\n" << simDataArray[i]->simIndex  << "\n";
                out << "Number of Masters:\n" << simDataArray[i]->masters << "\n";
                out << "Maximum packet size:\n" << simDataArray[i]->maxpacket << "\n";
                out << "Minimum packet size:\n" << simDataArray[i]->minpacket << "\n";
                out << "Number of collisions:\n" << simDataArray[i]->colisions << "\n";
                out << "Number of received:\n" << simDataArray[i]->received << "\n";
            }
            simFile.close();
        }

    }
    else{
       QTextStream out(&simFile);
       out << "Number of simulations run:\n" << simCount << "\n";
       for(int i = 0; i <simCount; i++)
       {
           out << "Simulation number:\n" << simDataArray[i]->simIndex  << "\n";
           out << "Number of Masters:\n" << simDataArray[i]->masters << "\n";
           out << "Maximum packet size:\n" << simDataArray[i]->maxpacket << "\n";
           out << "Minimum packet size:\n" << simDataArray[i]->minpacket << "\n";
           out << "Number of collisions:\n" << simDataArray[i]->colisions << "\n";
           out << "Number of received:\n" << simDataArray[i]->received << "\n";
       }
       simFile.close();
   }
}


void MainWindow::on_actionExit_triggered()
{
    //still need to add this
    trace("Ask to save, then exit.");


}

void MainWindow::process_line(QString myLine)
{
    myLine;
}

